home *** CD-ROM | disk | FTP | other *** search
- /*
- * Modifications to existing pc.c module are --
- *
- * Copyright (c) 1987
- * Louis A. Mamakos
- *
- * This work, or any derivations thereof may be used for non-commercial
- * purposes only. So there.
- */
-
- /* OS- and machine-dependent stuff for the Commodore-Amiga 1000 */
-
- #define AMIGAVERSION "3"
-
- #include <exec/types.h>
- #include <functions.h>
- /* for Manx Aztec C, get func returns */
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <exec/ports.h>
- #include <exec/devices.h>
- #include <exec/io.h>
-
- #include <devices/console.h>
- #include <devices/serial.h>
- #include <devices/timer.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <intuition/intuition.h>
-
- #include <stdio.h>
- #include "machdep.h"
- #include "amiga.h"
- #include "mbuf.h"
- #include "internet.h"
- #include "iface.h"
- #include "cmdparse.h"
- #include "slip.h"
- #include "timer.h"
- #include "netuser.h"
- #include "ip.h"
- #include "tcp.h"
- #ifdef TRACE
- #include "trace.h"
- #endif
-
- static char *copyright_notice[2] = {
- "AMIGA port of KA9Q TCP/IP (C) Copyright 1987 Louis A. Mamakos\r\n",
- "for non-commercial, non-profic use only\r\n"};
-
- struct asy asy[ASY_MAX];
-
- void *malloc();
-
- void setiss();
-
- /* Interface list header */
- struct interface *ifaces;
-
- struct IntuitionBase *IntuitionBase;
- static char banner[80];
- static struct NewWindow nw = {
- 0, 0, 640, 200, /* left, top, (max) width, (max) height */
- 0, 1, /* detail pen, block pen */
- 0, /* IDCMP flags */
- SMART_REFRESH | WINDOWDRAG | WINDOWDEPTH | WINDOWSIZING |
- SIZEBBOTTOM | ACTIVATE | NOCAREREFRESH, /* window flags */
- NULL, NULL, /* gadget, checkmark */
- (UBYTE *)&banner[0], /* title of window */
- NULL, NULL, /* screen, bitmap */
- 200, 50, -1, -1, /* sizing limits */
- WBENCHSCREEN, /* on the workbench */
- };
-
- APTR oldwindowptr;
- struct Process *mytask;
-
- struct MsgPort *keyboard, *consinp, *consoutp, *serinp, *seroutp,
- *timerp;
- struct IOExtSer serin, serout;
- struct IOStdReq consin, consout;
- struct timerequest tr;
- struct Window *win;
-
- char InputCharacter;
-
- int timeropen, serialopen;
- #ifdef AMIGADEVDRV
- int DeviceSignal;
- #endif
- struct timer worktimer; /* this is NOT a timer.device timer */
- void worker();
- #ifdef LATTICE
- extern struct { short error; char *msg; } os_errlist[];
- extern int _OSERR, os_nerr;
- #endif
- static
- clean(why)
- char *why;
- {
- int i;
-
- #ifdef AMIGADEVDRV
- if (DeviceSignal >= 0)
- FreeSignal(DeviceSignal);
- #endif
- if (timeropen)
- CloseDevice(&tr);
- if (serialopen)
- CloseDevice(&serin);
- if (win)
- CloseWindow(win);
- if (consinp)
- DeletePort(consinp);
- if (consoutp)
- DeletePort(consoutp);
- if (serinp)
- DeletePort(serinp);
- if (seroutp)
- DeletePort(seroutp);
- if (timerp)
- DeletePort(timerp);
-
- mytask->pr_WindowPtr = oldwindowptr;
-
- if (why) {
- myoserr(why);
- }
- exit(0);
- }
- myoserr(why)
- char *why;
- {
- int i;
- fprintf(stderr, "%s: ", why);
- #ifdef LATTICE
- fprintf(stderr, "%d: ", _OSERR);
-
- for(i = 0; os_errlist[i].error < os_nerr; i++)
- if (os_errlist[i].error == _OSERR)
- fprintf(stderr, os_errlist[i].msg);
- #endif
- fprintf(stderr, "\r\n");
- }
- /* Called at startup time to set up console I/O, memory heap */
- ioinit()
- {
- extern char major_rev[], minor_rev[];
- struct Screen *scr;
-
- mytask = (struct Process *) FindTask((char *) NULL);
- oldwindowptr = mytask->pr_WindowPtr;
- mytask->pr_WindowPtr = (APTR) -1; /* disable DOS requestors */
-
- if ((IntuitionBase = (struct IntuitionBase *)
- OpenLibrary("intuition.library", 33L)) == NULL)
- clean("No intuition: Version 1.2 of Amiga Systems Software required");
-
- sprintf(banner,
- #ifdef AMIGADEVDRV
- "KA9Q Internet Protocol Package, v%s.%s (Amiga version %sD)",
- #else
- "KA9Q Internet Protocol Package, v%s.%s (Amiga version %s)",
- #endif
- major_rev, minor_rev, AMIGAVERSION);
-
- /*
- * Try to determine the size of the workbench screen
- */
- scr = malloc(sizeof(struct Screen));
- if (scr==NULL)
- clean("Can't alloc screen");
-
- if (GetScreenData(scr, (ULONG) sizeof(struct Screen),
- WBENCHSCREEN, NULL) == TRUE) {
- nw.Width = scr->Width;
- nw.Height = scr->Height-20;
- nw.TopEdge = 19;
- } else
- fprintf(stderr, "Can't GetScreenData()\n");
-
- free((char *)scr);
- if ((win = OpenWindow(&nw)) == NULL)
- clean("Can't open window");
-
- if ((consinp = CreatePort("net:console in", 0L)) == NULL)
- clean("Can't create console port");
-
- if ((consoutp = CreatePort("net:console out", 0L)) == NULL)
- clean("Can't create console port");
-
- if ((timerp = CreatePort("net:timer", 0L)) == NULL)
- clean("Can't create timer port");
-
- consin.io_Data = (APTR) win;
- consin.io_Length = sizeof(struct Window);
-
- if (OpenDevice("console.device", 0L, &consin, 0L) != 0L)
- clean("Can't open console device");
-
- consout = consin;
-
- consin.io_Message.mn_ReplyPort = consinp;
- consin.io_Length = 1;
- consin.io_Data = (APTR) &InputCharacter;
- consin.io_Command = CMD_READ;
- SendIO(&consin);
- consout.io_Message.mn_ReplyPort = consoutp;
- consout.io_Command = CMD_WRITE;
-
- /* create and start up timer */
- tr.tr_node.io_Message.mn_ReplyPort = timerp;
- if (OpenDevice("timer.device", UNIT_VBLANK, &tr, 0L) != 0L)
- clean("Can't open timer");
- #ifdef AMIGADEVDRV
- if ((DeviceSignal = AllocSignal(-1)) == -1)
- clean("Can't allocate device signal");
- #endif
- timeropen++;
- tr.tr_node.io_Command = TR_GETSYSTIME;
- DoIO(&tr);
- #ifdef DEBUG
- printf("System time is %ld\n", tr.tr_time.tv_secs);
- #endif
- setiss(tr.tr_time.tv_secs);
- tr.tr_node.io_Command = TR_ADDREQUEST;
- tr.tr_time.tv_secs = 0;
- tr.tr_time.tv_micro = MSPTICK*1000L; /* convert to microseconds */
- SendIO(&tr);
-
- set_timer(&worktimer, 1500); /* set for 1.5 seconds */
- worktimer.func = worker;
- #ifdef AMIGADEVDRV
- DriverInit(); /* install internet.device driver */
- #endif
- start_timer(&worktimer);
- }
-
- /* Called just before exiting to restore console state */
- iostop()
- {
- while(ifaces != NULLIF){
- if(ifaces->stop != NULLFP)
- (*ifaces->stop)(ifaces);
- ifaces = ifaces->next;
- }
- #ifdef AMIGADEVDRV
- DriverShutdown();
- #endif
- clean((char *)0);
- }
-
- #define BUFMAXCNT 150
- static char conbuf[BUFMAXCNT];
- static int concnt = 0;
-
- int
- amigaputchar(c)
- char c;
- {
- conbuf[concnt++] = c;
- if ((c == '\n') || (concnt == BUFMAXCNT))
- amigaflush();
- return c;
- }
-
- amigaflush()
- {
- if (concnt == 0)
- return;
- consout.io_Data = (APTR) conbuf;
- consout.io_Length = concnt;
- consout.io_Command = CMD_WRITE;
- DoIO(&consout);
- concnt = 0;
- }
-
- /*
- * Begin terrible, horrible hack. All output should be printed upon (into?)
- * the window we opened before. Here goes nothing...
- */
- void
- printf(a, b, c, d, e, f, g, h, i, j, k)
- char *a;
- int b, c, d, e, f, g, h, i, j, k;
- {
- if (concnt)
- amigaflush();
-
- sprintf(conbuf, a, b, c, d, e, f, g, h, i, j, k);
- consout.io_Data = (APTR) conbuf;
- consout.io_Length = strlen(conbuf);
- consout.io_Command = CMD_WRITE;
- DoIO(&consout); /* no use in doing this async */
- }
-
-
- /* check active connections and update titles */
- void
- check_connections()
- {
- extern struct tcb *tcbs[NTCB];
- register struct tcb *tcb;
- register int i;
- int newlisten, newopn;
- static int listen = -1, opn = -1;
- static msg[80];
-
- newlisten = newopn = 0;
-
- for(i=0; i<NTCB; i++)
- for(tcb=tcbs[i]; tcb != NULLTCB; tcb = tcb->next)
- if (tcb->state == LISTEN)
- newlisten++;
- else
- newopn++;
-
- if (newlisten != listen || newopn != opn) {
- listen = newlisten;
- opn = newopn;
- sprintf(msg,
- "Amiga Port by WA3YMH (TCP: listen: %d open: %d)", listen, opn);
- SetWindowTitles(win, -1L, msg);
- }
- }
-
- /* called every second or so */
- void
- worker()
- {
- check_connections();
- start_timer(&worktimer);
- }
-
- #if 0
- /* processes any messages that Intuition sends us */
- void
- Do_Intuition_Message(m)
- register struct IntuiMessage *m;
- {
- ULONG class;
- USHORT code, qualifier;
-
- class = m->Class;
- code = m->Code;
- qualifier = m->Qualifier;
- ReplyMsg((struct Message *) m); /* reply msg back to Intuition */
- switch (class) {
- case INTUITICKS:
- check_connections();
- break;
- }
- }
- #endif
-
-
- /*
- * wait for something to happen
- */
- eihalt()
- {
- register struct IntuiMessage *msg;
- static ULONG mask = 0;
-
- if (mask == 0L)
- mask = 1L << consinp->mp_SigBit |
- 1L << serinp->mp_SigBit |
- 1L << timerp->mp_SigBit |
- #ifdef AMIGDEVDRV
- 1L << DeviceSignal |
- #endif
- #if 0
- 1L << win->UserPort->mp_SigBit |
- #endif
- 1L << seroutp->mp_SigBit;
-
- (void) Wait(mask);
- #if 0
- while (msg = (struct IntuiMessage *)GetMsg(win->UserPort))
- Do_Intuition_Message(msg);
- #endif
- }
-
- /* checks the time then ticks and updates ISS */
- void
- check_time()
- {
- int32 iss();
-
- if (CheckIO(&tr)) {
- WaitIO(&tr);
- (void) GetMsg(timerp);
- tick();
- (void)iss();
- tr.tr_time.tv_secs = 0;
- tr.tr_time.tv_micro = MSPTICK*1000L;
- /* convert to microseconds */
- SendIO(&tr);
- }
- }
-
- /* Initialize asynch port "dev" */
-
-
- /*
- * We will make the bold and rash assumption that the asy link will be used
- * for slip and slip-like stuff. That is, we assume that there is an
- * an end-of-frame character that we can have the serial.device driver look
- * for. Thus, we can fire up a single I/O request and have the whole frame
- * come back at once.
- */
- int
- asy_init(dev, bufsize)
- int16 dev;
- unsigned bufsize;
- {
- char serinitstr[1];
- int serinitlen;
-
- serinitstr[0] = FR_END; /* initialize initialization string to a */
- serinitlen = 1; /* frame end to flush receiver */
-
- if (serialopen) {
- printf("\namiga: Error - serial device already open.\n");
- return 0;
- }
- if ((serinp = CreatePort("net:serin", 0L)) == NULL)
- clean("Can't create serial input port");
-
- if ((seroutp = CreatePort("net:serout", 0L)) == NULL)
- clean("Can't create serial output port");
-
- /*
- * Open serial device.
- */
- serin.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE; /* ? */
- serin.io_Status = 0;
- serin.io_RBufLen = bufsize;
- asy[dev].speed = serin.io_Baud = 2400; /* default speed */
- if (OpenDevice("serial.device", 0L, &serin, 0L) != 0L)
- clean("Can't open serial device");
- serialopen++;
- serin.IOSer.io_Message.mn_ReplyPort = serinp;
- serout = serin;
- serout.IOSer.io_Message.mn_ReplyPort = seroutp;
- asy[dev].buflen = bufsize;
- /* alloc input buffer */
- if((asy[dev].input_buffer = malloc(asy[dev].buflen)) == NULL)
- clean("Can't allocate serial input buf");
- serin.IOSer.io_Data = (APTR) asy[dev].input_buffer;
- serin.IOSer.io_Length = asy[dev].buflen;
- asy[dev].input_len = 0; /* clear input buffer */
- serin.io_SerFlags = SERF_XDISABLED|SERF_EOFMODE|SERF_RAD_BOOGIE;
- serin.IOSer.io_Flags = 0;
- SendIO(&serin);
- serout.IOSer.io_Data = (APTR) serinitstr;
- serout.IOSer.io_Length = serinitlen;
- serout.IOSer.io_Command = CMD_WRITE;
- serout.IOSer.io_Flags = 0;
- serout.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;
- DoIO(&serout);
- }
-
- int
- asy_stop(iface)
- struct interface *iface;
- {
- if (iface->dev >= ASY_MAX) {
- fprintf(stderr, "asy_stop: bad dev %d\n", iface->dev);
- return;
- }
- AbortIO(&serin);
- AbortIO(&serout);
- CloseDevice(&serin);
- free(asy[iface->dev].input_buffer); /* release buffer */
- serialopen--;
- }
-
- /* Set asynch line speed */
- int
- asy_speed(dev,speed)
- int dev;
- int speed;
- {
- if (serialopen == 0)
- return;
-
- AbortIO(&serin);
- WaitIO(&serin);
- (void) GetMsg(serinp);
- asy[dev].speed = serin.io_Baud = speed;
- serin.io_ReadLen = 8;
- serin.io_WriteLen = 8;
- serin.io_StopBits = 1;
- serin.io_TermArray.TermArray0 = serin.io_TermArray.TermArray1 =
- (ULONG)FR_END << 24 | (ULONG)FR_END << 16 | FR_END << 8 | FR_END;
- serin.IOSer.io_Command = SDCMD_SETPARAMS;
- serin.IOSer.io_Flags = 0;
- DoIO(&serin);
- if (serin.IOSer.io_Error)
- printf("Bad I/O status %d on SETPARAMS\n",
- serin.IOSer.io_Error);
-
- serin.IOSer.io_Command = CMD_READ;
- serin.IOSer.io_Data = (APTR) asy[dev].input_buffer;
- serin.IOSer.io_Length = asy[dev].buflen;
- asy[dev].input_len = 0; /* clear input buffer */
- serin.io_SerFlags = SERF_XDISABLED|SERF_EOFMODE|SERF_RAD_BOOGIE;
- serin.IOSer.io_Flags = 0; /* no quick I/O */
- SendIO(&serin);
- }
-
- /* Send a buffer to serial transmitter */
- asy_output(dev,buf,cnt)
- unsigned dev;
- char *buf;
- unsigned short cnt;
- {
- /*
- * We 'know' that the transmitter is ready since we would not have
- * been called unless the previous I/O has been completed.
- */
- WaitIO(&serout);
- GetMsg(seroutp);
- serout.IOSer.io_Data = (APTR) buf;
- serout.IOSer.io_Length = cnt;
- serout.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE;
- serout.IOSer.io_Flags = 0; /* no quick I/O */
- serout.IOSer.io_Command = CMD_WRITE;
- SendIO(&serout);
- }
-
- /* Read characters from the keyboard, translating them to "real" ASCII
- * If none are ready, return the -1 from kbraw()
- */
- kbread()
- {
- char c;
-
- if (CheckIO(&consin)) {
- WaitIO(&consin);
- (void) GetMsg(consinp);
- c = InputCharacter;
- consin.io_Length = 1;
- consin.io_Data = (APTR) &InputCharacter;
- consin.io_Command = CMD_READ;
- SendIO(&consin); /* start next read up */
- return (c & 0xff);
- }
-
- return -1; /* nuthin here */
- }
-
- /* Receive characters from asynch line
- * Returns count of characters read
- */
- unsigned
- asy_recv(dev,buf,cnt)
- int dev;
- char *buf;
- unsigned cnt;
- {
- register int actual = 0;
- register long error;
-
- if (asy[dev].input_len == 0) { /* if buffer is empty.. */
- if (CheckIO(&serin) == NULL) /* see if I/O has completed */
- return 0; /* nope, not yet. */
- if (error = WaitIO(&serin))
- printf("(SERIN) WaitIO returns %d\n", error);
- if (serin.IOSer.io_Error)
- printf("Bad I/O stat %d (SERIN)\n",
- serin.IOSer.io_Error);
- (void) GetMsg(serinp);
- /* input has completed. fill in state variables */
- asy[dev].input_len = serin.IOSer.io_Actual;
- asy[dev].input_p = asy[dev].input_buffer;
- #ifdef TRACE
- if (trace & 0x40000000) {
- int a, n, l = asy[dev].input_len;
- unsigned char *b = asy[dev].input_buffer;
-
- a = 0;
- printf("Raw serial input:\r\n");
- while (l) {
- n = min(l, 16);
- fmtline(a, b, n);
- a += n;
- b += n;
- l -= n;
- }
- fflush(stdout);
- }
- #endif
- }
-
- if (asy[dev].input_len) { /* any chars in buffer left? */
- actual = min(asy[dev].input_len, cnt);
- if (actual == 1)
- *buf = *asy[dev].input_p; /* usual case */
- else
- movmem(asy[dev].input_p, buf, actual);
- asy[dev].input_len -= actual;
- asy[dev].input_p += actual;
- }
-
- if (asy[dev].input_len == 0) { /* if buffer is now empty */
- serin.IOSer.io_Command = CMD_READ;
- serin.IOSer.io_Data = (APTR) asy[dev].input_buffer;
- serin.IOSer.io_Length = asy[dev].buflen;
- serin.io_SerFlags =
- SERF_XDISABLED|SERF_EOFMODE|SERF_RAD_BOOGIE;
- serin.IOSer.io_Flags = 0; /* no quick I/O */
- SendIO(&serin);
- }
-
- return actual;
- }
-
- int
- stxrdy(dev)
- {
- return (CheckIO(&serout) != NULL);
- }
-
- /* Create a directory listing in a temp file and return the resulting file
- * descriptor. If full == 1, give a full listing; else return just a list
- * of names.
- *
- * This function is very dependent on the workings of Aztec standard I/O;
- * it uses their mechanism for generating and deleting temporary files.
- */
- FILE *
- dir(path,full)
- char *path;
- int full;
- {
- /*return (FILE *)NULL;*/
- return(0L);
- }
-
- #if 0
- bcmp(a,b,n)
- register char *a,*b;
- register int16 n;
- {
- while(n-- != 0){
- if(*a++ != *b++)
- return 1;
- }
- return 0;
- }
- #endif
-